package model

import (
	"fmt"
	"gowork/shuttleBus/utils"
	"time"
)

type Staff struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Route struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	DepartureStaition string
	DepartureTime string
	Terminus string
	ArrivalTime string
	Stopover bool
	SiteList []*Site `xorm:"-"`
	ShiftType int
	RunningTimeList []*RouteRunningTime `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type RouteRunningTime struct {
	Id int64 `xorm:"pk autoincr"`
	RouteId int64
	Name string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type RouteSite struct {
	Id int64 `xorm:"pk autoincr"`
	RouteId int64
	SiteId int64
	Sort int
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Site struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	Address string
	Sort int `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ApplyShuttleBus struct {
	Id int64 `xorm:"pk autoincr"`
	StaffId int64
	RouteId int64
	RouteName string
	ApplyDate string
	AuditStatus int
	CreatedAt time.Time
	UpdatedAt time.Time
}

func ZellerWeek(year, month, day int) string {

	var weekday = [7]string{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}

	var y, m, c int
	if month >= 3 {
		m = month
		y = year % 100
		c = year / 100
	} else {
		m = month + 12
		y = (year - 1) % 100
		c = (year - 1) / 100
	}

	week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
	if week < 0 {
		week = 7 - (-week)%7
	} else {
		week = week % 7
	}
	which_week := week
	return weekday[which_week]
}

func GetMonth(m string) int{
	switch m {
	case "January":
		return 1
	case "February":
		return 2
	case "March":
		return 3
	case "April":
		return 4
	case "May":
		return 5
	case "June":
		return 6
	case "July":
		return 7
	case "August":
		return 8
	case "September":
		return 9
	case "October":
		return 10
	case "November":
		return 11
	case "December":
		return 12
	}
	return 0
}

func BubbleSort(arr []*Site) []*Site{
	for i := 0; i < len(arr)-1; i++ {
		for j := 0; j < len(arr)-i-1; j++ {
			if arr[j].Sort > arr[j+1].Sort {
				//temp := arr[j]
				//arr[j] = arr[j+1]
				//arr[j+1] = temp

				arr[j], arr[j+1] = arr[j+1], arr[j]
			}
		}
	}
	return arr
}

func (route *Route)CreateRoute(r *Route)(map[string]interface{}, error){

	w := new(utils.Worker)
	r.Id = w.GetId()
	r.CreatedAt = time.Now()
	r.UpdatedAt = time.Now()
	x.Insert(r)

	for _, s := range r.SiteList{

		var rs = RouteSite{
			Id:        w.GetId(),
			RouteId:   r.Id,
			SiteId:    s.Id,
			Sort:      s.Sort,
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		}
		x.Insert(&rs)
	}

	for _, rt := range r.RunningTimeList{
		rt.Id = w.GetId()
		rt.RouteId = r.Id
		x.Insert(rt)
	}

	return map[string]interface{}{"message": "成功","code":200}, nil
}

func (route *Route)QueryRoute(rId int64)(*Route, error){

	var r Route
	x.Id(rId).Get(&r)


	x.Join("INNER", "route_site", "route_site.site_id = site.id").Where("route_site.route_id = ?", r.Id).Find(&r.SiteList)

	for _, s := range r.SiteList{

		var rs RouteSite
		x.Where("route_id = ?", r.Id).And("site_id = ?", s.Id).Get(&rs)

		s.Sort = rs.Sort

	}

	r.SiteList = BubbleSort(r.SiteList)

	return &r, nil
}

func (route *Route)AppointmentShuttleBus(sId int64, rList []*Route, dList []string)(map[string]interface{}, error){

	w := new(utils.Worker)

	for _, d := range dList {
		for _, r := range rList {
			var asb ApplyShuttleBus
			x.Where("staff_id = ?", sId).And("route_id = ?", r.Id).And("apply_date = ?", d).Get(&asb)
			if asb.Id != 0{
				return map[string]interface{}{"message": d + "日已存在预约记录，无需再次预约","code":400}, nil
			}

			var newAsb = ApplyShuttleBus{
				Id:        w.GetId(),
				StaffId:   sId,
				RouteId:   r.Id,
				RouteName: r.Name,
				ApplyDate: d,
				AuditStatus : 1,
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
			}
			x.Insert(&newAsb)
		}
	}

	return map[string]interface{}{"message": "成功","code":200}, nil
}

func (route *Route)ShuttleBus(t time.Time)([]*Route, error){

	var rList []*Route
	x.Join("INNER", "route_running_time", "route_running_time.route_id = route.id").
		Where("route_running_time.name = ?", ZellerWeek(t.Year(), GetMonth(t.Month().String()), t.Day())).
		Find(&rList)

	return rList, nil
}

func (route *Route)ByCar(sId int64, rId int64)(map[string]interface{}, error){

	fmt.Println("sId：", sId)
	fmt.Println("rId：", rId)

	var asb ApplyShuttleBus
	x.SQL("select * from apply_shuttle_bus where staff_id = ? and route_id = ? and apply_date = ?", sId, rId, time.Now().Format("2006-01-02")).Get(&asb)
	//x.Where("staff_id = ?", sId).And("route_id = ", rId).And("apply_date = ?", time.Now().Format("2006-01-02")).Get(&asb)
	fmt.Println("asb：", asb)
	if asb.Id != 0 && (asb.AuditStatus == 2){
		return map[string]interface{}{"message": "成功","code":200}, nil
	}

	return map[string]interface{}{"message": "没有预约或审核未通过","code":400}, nil
}